home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d18
/
nrpas13.arc
/
ANNEAL.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-05-01
|
5KB
|
172 lines
PROCEDURE anneal(x,y : cityarray; VAR iorder: iarray; ncity: integer);
(* Programs using routine ANNEAL must define types
cityarray : ARRAY [1..ncity] OF real;
iarray : ARRAY [1..ncity] OF integer;
in the main routine. *)
LABEL 10,20,99;
CONST
tfactr = 0.9;
TYPE
nsix = ARRAY [1..6] OF integer;
VAR
ans : boolean;
path,de,t : real;
nover,nlimit,i1,i2,idum,iseed: integer;
i,j,k,nsucc,nn,idec : integer;
n : nsix;
FUNCTION alen(x1,x2,y1,y2: real): real;
BEGIN
alen := sqrt(sqr(x2-x1)+sqr(y2-y1))
END;
PROCEDURE revcst(x,y: cityarray; iorder: iarray; ncity: integer;
VAR n: nsix; VAR de: real);
VAR
xx,yy : ARRAY [1..6] OF real;
j,ii : integer;
BEGIN
n[3] := 1 + ((n[1]+ncity-2) MOD ncity);
n[4] := 1 + (n[2] MOD ncity);
FOR j := 1 TO 4 DO BEGIN
ii := iorder[n[j]];
xx[j] := x[ii];
yy[j] := y[ii]
END;
de := -alen(xx[1],xx[3],yy[1],yy[3])-alen(xx[2],xx[4],yy[2],yy[4])
+alen(xx[1],xx[4],yy[1],yy[4])+alen(xx[2],xx[3],yy[2],yy[3])
END;
PROCEDURE reverse(VAR iorder: iarray; ncity: integer; n: nsix);
VAR
nn,j,k,l,itmp : integer;
BEGIN
nn := (1+((n[2]-n[1]+ncity) MOD ncity)) DIV 2;
FOR j := 1 TO nn DO BEGIN
k := 1 + ((n[1]+j-2) MOD ncity);
l := 1 + ((n[2]-j+ncity) MOD ncity);
itmp := iorder[k];
iorder[k] := iorder[l];
iorder[l] := itmp
END
END;
PROCEDURE trncst(x,y: cityarray; iorder: iarray; ncity: integer;
VAR n: nsix; VAR de: real);
VAR
xx,yy : ARRAY [1..6] OF real;
j,ii : integer;
BEGIN
n[4] := 1 + (n[3] MOD ncity);
n[5] := 1 + ((n[1]+ncity-2) MOD ncity);
n[6] := 1 + (n[2] MOD ncity);
FOR j := 1 TO 6 DO BEGIN
ii := iorder[n[j]];
xx[j] := x[ii];
yy[j] := y[ii]
END;
de := -alen(xx[2],xx[6],yy[2],yy[6])-alen(xx[1],xx[5],yy[1],yy[5])
-alen(xx[3],xx[4],yy[3],yy[4])+alen(xx[1],xx[3],yy[1],yy[3])
+alen(xx[2],xx[4],yy[2],yy[4])+alen(xx[5],xx[6],yy[5],yy[6])
END;
PROCEDURE trnspt(VAR iorder: iarray; ncity: integer; n: nsix);
CONST
maxcity=1000;
VAR
jorder : ARRAY [1..maxcity] OF integer;
m1,m2,m3,nn,j,jj : integer;
BEGIN
m1 := 1 + ((n[2]-n[1]+ncity) MOD ncity);
m2 := 1 + ((n[5]-n[4]+ncity) MOD ncity);
m3 := 1 + ((n[3]-n[6]+ncity) MOD ncity);
nn := 1;
FOR j := 1 TO m1 DO BEGIN
jj := 1 + ((j+n[1]-2) MOD ncity);
jorder[nn] := iorder[jj];
nn := nn+1
END;
IF (m2>0) THEN BEGIN
FOR j := 1 TO m2 DO BEGIN
jj := 1+((j+n[4]-2) MOD ncity);
jorder[nn] := iorder[jj];
nn := nn+1
END
END;
IF (m3>0) THEN BEGIN
FOR j := 1 TO m3 DO BEGIN
jj := 1 + ((j+n[6]-2) MOD ncity);
jorder[nn] := iorder[jj];
nn := nn+1
END
END;
FOR j := 1 TO ncity DO BEGIN
iorder[j] := jorder[j]
END
END;
PROCEDURE metrop(de,t: real; VAR ans: boolean);
(* Programs using routine METROP must declare the variable
VAR
gljdum : integer;
and initialize its value to
gljdum := 1;
in the main routine. *)
BEGIN
ans := (de<0.0) OR (ran3(gljdum)<exp(-de/t))
END;
BEGIN
nover := 100*ncity;
nlimit := 10*ncity;
path := 0.0;
t := 0.5;
FOR i := 1 TO (ncity-1) DO BEGIN
i1 := iorder[i];
i2 := iorder[i+1];
path := path+alen(x[i1],x[i2],y[i1],y[i2])
END;
i1 := iorder[ncity];
i2 := iorder[1];
path := path+alen(x[i1],x[i2],y[i1],y[i2]);
idum := -1;
iseed := 111;
FOR j := 1 TO 100 DO BEGIN
nsucc := 0;
FOR k := 1 TO nover DO BEGIN
10: n[1] := 1+trunc(ncity*ran3(idum));
n[2] := 1+trunc((ncity-1)*ran3(idum));
IF (n[2]>=n[1]) THEN n[2] := n[2]+1;
nn := 1+((n[1]-n[2]+ncity-1) MOD ncity);
IF (nn<3) THEN goto 10;
idec := irbit1(iseed);
IF (idec=0) THEN BEGIN
n[3] := n[2]+trunc(abs(nn-2)*ran3(idum))+1;
n[3] := 1+((n[3]-1) MOD ncity);
trncst(x,y,iorder,ncity,n,de);
metrop(de,t,ans);
IF ans THEN BEGIN
nsucc := nsucc+1;
path := path+de;
trnspt(iorder,ncity,n)
END
END ELSE BEGIN
revcst(x,y,iorder,ncity,n,de);
metrop(de,t,ans);
IF ans THEN BEGIN
nsucc := nsucc+1;
path := path+de;
reverse(iorder,ncity,n)
END
END;
IF (nsucc>=nlimit) THEN goto 20
END;
20: writeln;
writeln('T =',t:10:6,' Path Length =',path:12:6);
writeln('Successful Moves: ',nsucc:6);
t := t*tfactr;
IF (nsucc=0) THEN goto 99
END;
99:
END;